<?php
namespace restphp\core;

use restphp\aop\AopParam;
use restphp\biz\RestErrorCode;
use restphp\exception\RestException;
use restphp\Rest;

/**
 * 自动加载
 * @author sofical
 * @date 2017-03-17
 * @package restphp\core
 */
class RestLoad {
    public static function load($strName) {
        self::$arrMap[] = array(
            'tag' => 'restphp',
            'dir' => (DIR_RESTPHP . DIRECTORY_SEPARATOR)
        );
        self::$arrMap[] = array(
            'tag' => '',
            'dir' => (defined('DIR_LIB') ? DIR_LIB : 'lib') . DIRECTORY_SEPARATOR
        );
        if (!self::_loadRestphp($strName)) {
            if (Rest::isBuilding()) {
                die('cloud not load class:' . $strName . ' in library: ' . json_encode(self::$arrMap));
            } else {
                throw new RestException('cloud not load class:' . $strName, RestErrorCode::CODE_FILE_LOAD_ERROR);
            }
        }// or die('cloud not load class:' . $strName);
    }

    private static $arrMap = array(
    );

    private static $_classAopMap = null;

    private static function _callClassAop($strName){
        if (Rest::isBuilding()) {
            return;
        }
        if (null == self::$_classAopMap) {
            $strMapFile = DIR_BUILD_TARGET . DIRECTORY_SEPARATOR . '_annotation_' . DIRECTORY_SEPARATOR . '_restphp_aop_class_map.php';
            $strMapFile = str_replace("\\", DIRECTORY_SEPARATOR, $strMapFile);
            if (file_exists($strMapFile)) {
                self::$_classAopMap = include($strMapFile);
            } else {
                self::$_classAopMap = array();
            }
        }
        if (!isset(self::$_classAopMap[$strName])) {
            return;
        }

        $arrAop = self::$_classAopMap[$strName];
        foreach ($arrAop as $aop=>$processParams) {
            $reflection = new \ReflectionClass($aop);
            if ($reflection->hasMethod('before')) {
                $reflection->newInstance()->before(AopParam::instance($processParams, $strName));
            }
        }
    }

    public static function _loadRestphp($strName) {
        // 类前置aop引用
        self::_callClassAop($strName);

        // 优先加载aop 实现引用重构类
        $strAopTest = DIR_BUILD_TARGET . DIRECTORY_SEPARATOR . '_annotation_' . DIRECTORY_SEPARATOR . $strName . '.php';
        $strAopTest = str_replace("\\", DIRECTORY_SEPARATOR, $strAopTest);
        if (file_exists($strAopTest)) {
            include_once($strAopTest);
            return true;
        }

        foreach (self::$arrMap as $arrRoute) {
            if (substr($strName, 0, strlen($arrRoute['tag'])) == $arrRoute['tag']) {
                $filePath = $arrRoute['dir'] . substr($strName, strlen($arrRoute['tag'])) . '.php';
                $filePath = str_replace("\\", DIRECTORY_SEPARATOR, $filePath);
                $filePath = str_replace(DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, $filePath);
                if (file_exists($filePath)) {
                    include_once($filePath);
                    return true;
                }
            }
        }
        $strMaybe = $strName . '.php';
        $strMaybe = str_replace("\\", DIRECTORY_SEPARATOR, $strMaybe);
        if (file_exists($strMaybe)) {
            include_once($strMaybe);
            return true;
        }
        $strMaybePHPLib = 'src' . DIRECTORY_SEPARATOR . 'php' . DIRECTORY_SEPARATOR . $strMaybe;
        if (file_exists($strMaybePHPLib)) {
            include_once ($strMaybePHPLib);
            return true;
        }
        if (defined('DIR_BUILD')) {
            $arrDirRoot = explode("|", DIR_BUILD);
            foreach ($arrDirRoot as $dirRoot) {
                $strMayBUILDLib = $dirRoot . DIRECTORY_SEPARATOR . $strMaybe;
                if (file_exists($strMayBUILDLib)) {
                    include_once($strMayBUILDLib);
                    return true;
                }
            }
        }
        return false;
    }
}